/* label.cpp */

#include <dodo_plot/widget/label.h>
#include <dodo_plot/kernel/canvas.h>
#include <dodo_plot/kernel/plotter.h>
#include <dodo_plot/kernel/font.h>
#include <dodo_plot/kernel/basic_utils.h>

namespace dodo_plot
{
void Label::draw(Context_p cr, const Point& p) const
{
	cr->save();
	cr->begin_new_path();

	cr->set_font_face(font_.font_face());
	cr->set_font_size(font_size_);
	
	Cairo::TextExtents extents;
	cr->get_text_extents(text_, extents);
	
	double x_offset, y_offset;

	switch(align_mode_)
	{
	case LEFT:
		x_offset = 0;
		break;
	case RIGHT:
		x_offset = -(extents.width + extents.x_bearing);
		break;
	default:	//including CENTER
		x_offset = -(extents.width / 2 + extents.x_bearing);
	}
	// draw fill and border
	cr->rectangle(p.x + x_offset, p.y + extents.height + extents.y_bearing, 
		extents.width, -extents.height);
	set_cr_color(cr, fill_color_);
	cr->fill_preserve();

	cr->set_line_width(1.0);
	set_cr_color(cr, border_color_);
	cr->stroke();

	// draw text
	set_cr_color(cr, color_);

	cr->move_to(p.x + x_offset, p.y);
	cr->show_text(text_);

	cr->restore();
}

void Label::draw(const Plotter& plotter) const
{
	Context_p cr = plotter.get_cr();
	cr->save();


	Point p = plotter.get_abs_point(0, 0);
	
	cr->set_font_face(font_.font_face());
	cr->set_font_size(font_size_);
	
	Cairo::TextExtents extents;
	cr->get_text_extents(text_, extents);
	
	double x_offset, y_offset;

	switch(align_mode_)
	{
	case LEFT:
		x_offset = 0;
		break;
	case RIGHT:
		x_offset = -(extents.width + extents.x_bearing);
		break;
	default:	//including CENTER
		x_offset = -(extents.width / 2 + extents.x_bearing);
	}
	// draw fill and border
	cr->rectangle(p.x + x_offset, p.y + extents.height + extents.y_bearing, 
		extents.width, -extents.height);
	set_cr_color(cr, fill_color_);
	cr->fill_preserve();

	cr->set_line_width(1.0);
	set_cr_color(cr, border_color_);
	cr->stroke();

	// draw text
	set_cr_color(cr, color_);

	cr->move_to(p.x + x_offset, p.y);
	cr->show_text(text_);

	cr->restore();
}

Label::Label(const std::string& text, 
	double font_size, 
	int align_mode, 
	const Color& color, 
	const Color& border_color,
	const Color& fill_color,
	const Font& font)
		:
	text_(text),
	font_size_(font_size),
	align_mode_(CENTER), //set to default first, then change it.
	color_(color),
	fill_color_(fill_color),
	border_color_(border_color),
	font_(font)
{
	set_align_mode(align_mode);
}

std::string Label::text() const
{
	return text_;
}

std::string Label::set_text(const std::string& new_text)
{
	std::string old_text(text_);
	text_ = new_text;
	return old_text;
}

std::string Label::append(const std::string& extra_text)
{
	std::string old_text(text_);
	text_.append(extra_text);
	return old_text;
}

std::string Label::append(const Label& l)
{
	return append(l.text());
}

Color Label::set_color(const Color& new_color)
{
	Color old_color(color_);
	color_ = new_color;
	return old_color;
}

Color Label::set_border_color(const Color& new_border_color)
{
	Color old_color(border_color_);
	border_color_ = new_border_color;
	return old_color;
}

Color Label::set_fill_color(const Color& new_fill_color)
{
	Color old_color(fill_color_);
	fill_color_ = new_fill_color;
	return old_color;
}

Font Label::set_font(const Font& new_font)
{
	Font old_font(font_);
	font_ = new_font;
	return old_font;
}

double Label::set_font_size(double new_font_size)
{
	double old_font_size(font_size_);
	font_size_ = new_font_size;
	return old_font_size;
}

int Label::set_align_mode(int new_align_mode)
{
	int old_mode(align_mode_);
	switch(new_align_mode)
	{
	case LEFT:		
	case RIGHT:
	case CENTER:
		align_mode_ = new_align_mode;
		break;
	default:
		; //not changing...
	}
	return old_mode;
}


}
